home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / mdl10.zoo / flicker.c < prev    next >
C/C++ Source or Header  |  1993-06-06  |  24KB  |  1,132 lines

  1. /*
  2.  *    flicker.c - display grayscale image with flicker mode
  3.  *
  4.  *    modified for dl/gl files. pimg points to all the raw images and
  5.  *    nframes is the number of frames. no histogram stuff at all. handles
  6.  *    dl commands (which is a list of frame indices in order).
  7.  *
  8.  *    note: I16 is 16 bit integer so we don't care what an "int" is
  9.  *    external to this routine. when u see 96000, it is really
  10.  *    48000 * sizeof(I16). most things here are actually tuned to 16 bit
  11.  *    ints.
  12.  *
  13.  *    now ansi for gcc. -mshort not needed.
  14.  *
  15.  *    compilation control:
  16.  *        NEW_RANDOM    def to use new random noise code
  17.  *        NO_INVERT    def to invert pixel intensities (normally
  18.  *                undefined)
  19.  */
  20.  
  21. typedef short I16;
  22. typedef unsigned short UI16;
  23.  
  24. #ifndef lint
  25. static char *rcsid = "$Id: flicker.c,v 1.3 1991/07/24 17:13:48 rosenkra Exp $";
  26. #endif
  27.  
  28. /*
  29.  * $Log: flicker.c,v $
  30.  * Revision 1.3  1991/07/24  17:13:48  rosenkra
  31.  * now RCS. fix flicker for SimpConv2Gray so image is not so dark. also
  32.  * make sure last work in each pixel row gets dumped to screen when
  33.  * using SimpConv2Gray (e.g. during cut or zoom).
  34.  *
  35.  * Revision 1.2  1991/07/16  23:24:48  rosenkra
  36.  * released june 91 to usenet. first RCS revision.
  37.  *
  38.  */
  39.  
  40. /*
  41.  *    this is for screen-switching on mono to simulate grayscale. it
  42.  *    uses a combination of floyd-steinberg and simulate "planes" which
  43.  *    get displayed each vblank. the image it works from should be
  44.  *    grayscale, i.e. each pixel is represented by an 8-bit (0 to 255)
  45.  *    intensity. since GIF images come with a color table, it is first
  46.  *    required to map each GIF pixel to the color table which has been
  47.  *    first changed to grayscale, either by averaging the rgb values
  48.  *    or by using the NTSC intensity equation.
  49.  *
  50.  *    note that i think the f-s algorithm employed here sweeps each row
  51.  *    left to right rather than alternating directions. that is why there
  52.  *    is spurious info in areas otherwise supposed to be white.
  53.  *
  54.  *    also, all points where chars are used in a calculation, they MUST
  55.  *    be unsigned.
  56.  *
  57.  *    return ptr to screens.
  58.  */
  59.  
  60. /* written by Klaus Pedersen (micro@imada.dk) */
  61. /* modified by Bill Rosenkranz (rosenkra@convex.com) */
  62.  
  63. #include <stdio.h>
  64. #include <types.h>
  65. #include <stdlib.h>    /* for malloc */
  66. #include <string.h>    /* for bzero */
  67. #include <osbind.h>
  68.  
  69.  
  70. #define LEVELS        4
  71. #define NUMERRS        1024
  72. #define SCRNSPACE    48256L        /* now per frame */
  73. #define MAXFRAMES    25        /* 25 needs 2.4 MB (96000B/frame) */
  74.  
  75.  
  76. /*
  77.  *    globals.
  78.  *
  79.  *    these are the thresholds for quantizing. 0,85,170,255 seem best
  80.  */
  81. static I16    _Levels[LEVELS]     = {  0,  85, 170, 255};
  82. static I16    _SimpLevels[LEVELS] = {  0, 255};
  83.  
  84. static int    _Show;            /* print progress to stdout if !=0 */
  85. static int    _Delay;            /* ms delay between frames (if +ve) */
  86. static I16    _Nframes;        /* number of frames in raster */
  87. static I16    _Ncommands;        /* number of commands */
  88. static I16    _Width;            /* image size */
  89. static I16    _Hight;
  90. static I16         _Beta;            /* for the Laplace filter */
  91. static I16         _MaxRandom;        /* for adding random noise */
  92. static I16     *_Err1,            /* the error propagation arrays */
  93.            *_Err2;
  94. static I16         _Err1Array[NUMERRS],
  95.             _Err2Array[NUMERRS];
  96.  
  97. static I16     *_Scrn,            /* we malloc space here */
  98.            *_Scrn1[MAXFRAMES],
  99.            *_Scrn2[MAXFRAMES],
  100.            *_Scrn3[MAXFRAMES];
  101.  
  102.  
  103.  
  104. /*
  105.  *    local functions
  106.  */
  107. static void    _Conv2Gray (unsigned char *, int *);
  108. static void    _SimpConv2Gray (unsigned char *, int *);
  109. static I16    _GenConvPix (unsigned char *, int, int);
  110. static I16    _SimpGenConvPix (unsigned char *, int, int);
  111. static I16    _Laplace (unsigned char *);
  112. static void    _ClearErr (void);
  113. static I16    _Rand (I16);
  114.  
  115.  
  116.  
  117.  
  118. /*------------------------------*/
  119. /*    dl_flicker        */
  120. /*------------------------------*/
  121. int dl_flicker (unsigned char *pimg, int nframes, int width, int hight,
  122.         int beta, int maxrandom, int opt, int delay, int *cmd,
  123.         int ncommands, int show)
  124.  
  125.         /* pimg        -> raster image sequence (intensities) */
  126.         /* nframes    number of frames in pimg */
  127.         /* width    width, pixels */
  128.         /* hight    height, pixels */
  129.         /* beta        for laplace filter */
  130.         /* maxrandom    for random noise */
  131.         /* opt        0=no flicker, 1=flicker */
  132.         /* delay    ms delay between images */
  133.         /* cmd        -> commands (order to display frames) */
  134.         /* ncommands    number of commands (total frames in loop) */
  135.         /* show        print info to stdout if != 0 */
  136. {
  137.  
  138. /*
  139.  *    this is the main entry point. complete grayscale raster image
  140.  *    comes from pimg with height and width specified. if beta != 0,
  141.  *    do Laplace filter with that beta. if maxrandom != 0, add some
  142.  *    random noise with that value (see below).
  143.  *
  144.  *    pimg contains each basic frame in succession.
  145.  *
  146.  *    dl commands are used. do this in loop showing the basic screens
  147.  *    by indexing into _Scrn* as _Scrn*[cmd[i]].
  148.  *
  149.  *    return 0 if ok. 1 if error.
  150.  */
  151.  
  152.  
  153.  
  154.     /*
  155.      *   set our globals
  156.      */
  157.     _Show      =       show;
  158.     _Nframes   = (I16) nframes;    /* number of frames in raster */
  159.     _Ncommands = (I16) ncommands;    /* number of commands in animation */
  160.     _Delay     =       delay;    /* ms delay between frames */
  161.     _Hight     = (I16) hight;    /* its height... */
  162.     _Width     = (I16) width;    /* ...and width */
  163.     _Beta      = (I16) beta;    /* Laplace filter coefficient */
  164.                     /* 1=0.25, 2=0.50, 3=0.75... (Try 4) */
  165.     _MaxRandom = (I16) maxrandom;    /* amount of random noise, 0-255 */
  166.                     /* for 0% to 100% noise. (Try 10) */
  167.  
  168.  
  169.  
  170.     /*
  171.      *   check nframes.
  172.      */
  173.     if (_Show)
  174.         printf ("flicker: num frames = %d, max allowed = %d\n",
  175.             _Nframes, MAXFRAMES);
  176.     if (_Nframes > MAXFRAMES)
  177.         _Nframes = MAXFRAMES;
  178.  
  179.  
  180.  
  181.     /*
  182.      *   allocate space for all screens. note that sizeof(I16) is 2.
  183.      */
  184.     if (opt)
  185.     {
  186.         if (_Show)
  187.             printf ("flicker: allocating memory, flicker mode (%ld bytes)\n",
  188.                 96000L * (long)_Nframes);
  189.         _Scrn = (I16 *) malloc (96000 * (size_t) _Nframes + 256);
  190.     }
  191.     else
  192.     {
  193.         if (_Show)
  194.             printf ("flicker: allocating memory, not flicker (%ld bytes)\n",
  195.                 32000L * (long)_Nframes);
  196.         _Scrn = (I16 *) malloc (32000 * (size_t) _Nframes + 256);
  197.     }
  198.     if (_Scrn == (I16 *) NULL)
  199.     {
  200.         if (_Show)
  201.             printf ("flicker: memory allocation failed\n");
  202.         return (1);
  203.     }
  204.  
  205.  
  206.  
  207.     /*
  208.      *   make sure screen is aligned on 256-byte boundary.
  209.      */
  210.     _Scrn = (I16 *) (((long) _Scrn + 256L) & 0xFFFFFF00L);
  211.  
  212.  
  213.  
  214.     /*
  215.      *   clear screens. this may not have to be done if malloc clears
  216.      *   or if the dithering touches everything
  217.      */
  218.     if (_Show)
  219.         printf ("flicker: clearing memory...\n");
  220.     if (opt)
  221.         bzero (_Scrn, (size_t) (96000 * _Nframes));
  222.     else
  223.         bzero (_Scrn, (size_t) (32000 * _Nframes));
  224.  
  225.  
  226.  
  227.     /*
  228.      *   do it!
  229.      */
  230.     if (opt)
  231.         _Conv2Gray (pimg, cmd);
  232.     else
  233.         _SimpConv2Gray (pimg, cmd);
  234.  
  235.  
  236.     return (0);
  237. }
  238.  
  239.  
  240.  
  241.  
  242. /*------------------------------*/
  243. /*    _Conv2Gray        */
  244. /*------------------------------*/
  245. static void _Conv2Gray (unsigned char *pic, int *cmd)
  246. {
  247.     unsigned char           *ppic;
  248.     register int        i;
  249.     int            j;
  250.     register I16            x;
  251.     I16                y;
  252.     I16            w;
  253.     I16            h;
  254.     register long            yoffset;
  255.     I16               *TmpErr;
  256.     register I16            q;
  257.     I16                rover1;
  258.     I16                rover2;
  259.     register UI16        pix;
  260.     unsigned char           *p;
  261.     char               *old1;
  262.     char               *old2;
  263.     int            rpt;
  264.     int            done;
  265.  
  266.  
  267.  
  268.  
  269.     /*
  270.      *   number of times to repeat inner display loop showing a single
  271.      *   frame. this is to deal with different frame rates. 40 ms for
  272.      *   three Setscreen/Vsync is about right on 8MHz ST...
  273.      */
  274.     rpt = _Delay / 40;
  275.  
  276.  
  277.  
  278.     /*
  279.      *   save old screen info
  280.      */
  281.     old1  = (char *) Logbase ();
  282.     old2  = (char *) Physbase ();
  283.  
  284.  
  285.  
  286.     /*
  287.      *   clear...
  288.      */
  289.     if (_Show)
  290.         printf ("flicker: clear screen...\n");
  291.     bzero (old1, (size_t) 32000);
  292.     bzero (old2, (size_t) 32000);
  293.  
  294.  
  295.  
  296.     /*
  297.      *   we will set physbase to our buffer and _Scrn1[0] points to it.
  298.      *   set the other screen pointers. _Scrn is a buffer large enuf
  299.      *   to hold all 3 screens for every frame. it would obviously be
  300.      *   more efficient to blit the images rather than store the entire
  301.      *   screen if the image is smaller than the entire screen.
  302.      *